package com.whc.gulimall.ware.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whc.common.to.OrderTO;
import com.whc.common.to.SkuHasStockVo;
import com.whc.common.to.mq.StockDetailTo;
import com.whc.common.to.mq.StockLockedTO;
import com.whc.common.utils.PageUtils;
import com.whc.common.utils.Query;
import com.whc.common.utils.R;
import com.whc.common.utils.RRException;
import com.whc.gulimall.ware.constant.OrderStatusEnum;
import com.whc.gulimall.ware.dao.WareSkuDao;
import com.whc.gulimall.ware.entity.WareOrderTaskDetailEntity;
import com.whc.gulimall.ware.entity.WareOrderTaskEntity;
import com.whc.gulimall.ware.entity.WareSkuEntity;
import com.whc.gulimall.ware.feign.OrderFeignService;
import com.whc.gulimall.ware.service.WareOrderTaskDetailService;
import com.whc.gulimall.ware.service.WareOrderTaskService;
import com.whc.gulimall.ware.service.WareSkuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author angaoen
 */

@Service("wareSkuService")
@Slf4j
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    /**
     * 库存工作单
     */
    @Resource
    private WareOrderTaskDetailService wareOrderTaskDetailService;

    /**
     * 库存工作单
     */
    @Resource
    private WareOrderTaskService wareOrderTaskService;

    @Resource
    private OrderFeignService orderFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<WareSkuEntity> queryWrapper = new QueryWrapper<>();
        String skuId = (String) params.get("skuId");
        if (StrUtil.isNotBlank(skuId) && !"0".equals(skuId)) {
            queryWrapper.eq("sku_id", skuId);
        }

        String wareId = (String) params.get("wareId");
        if (StrUtil.isNotBlank(wareId) && !"0".equals(wareId)) {
            queryWrapper.eq("ware_id", wareId);
        }

        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    /**
     * 根据skuId和wareId更新库存
     *
     * @param skuId  商品Id
     * @param wareId 仓库id
     * @param skuNum 商品数量
     */
    @Override
    public void updateStockBySkuIdAndWareId(Long skuId, Long wareId, Integer skuNum) {
        baseMapper.updateStockBySkuIdAndWareId(skuId, wareId, skuNum);
    }

    /**
     * 获取对应商品是否有库存
     *
     * @param skuIds 商品id列表
     * @return 返回结果
     */
    @Override
    public List<SkuHasStockVo> listHasStockBySkuIds(List<Long> skuIds) {
        return baseMapper.listHasStockBySkuIds(skuIds);
    }

    /**
     * 解锁库存
     *
     * @param to t0
     * @throws Exception 异常
     */
    @Override
    public void unlockStock(StockLockedTO to) throws Exception {
        // 工作单详情
        StockDetailTo stockDetailTo = to.getStockDetailTo();
        Long detailId = stockDetailTo.getId();
        WareOrderTaskDetailEntity detailEntity = wareOrderTaskDetailService.getById(detailId);
        if (detailEntity != null) {
            // 库存工作单ID
            Long id = to.getId();
            WareOrderTaskEntity taskEntity = wareOrderTaskService.getById(id);
            if (taskEntity != null) {
                R r = orderFeignService.getOrderStatusByOrderSN(taskEntity.getOrderSn());
                if (Objects.equals(0, r.getCode())) {
                    Integer orderStatus = r.getData(new TypeReference<Integer>() {
                    });
                    // 只有(状态不为空或者状态为取消状态)且订单必须是已经锁定状态
                    if ((orderStatus != null || Objects.equals(orderStatus, OrderStatusEnum.CANCLED.getCode()))
                            && Objects.equals(stockDetailTo.getLockStatus(), 1)) {
                        baseMapper.unlockStock(detailEntity.getSkuId(), detailEntity.getSkuNum(),
                                detailEntity.getWareId());
                        // 修改状态
                        wareOrderTaskDetailService
                                .update(new UpdateWrapper<WareOrderTaskDetailEntity>()
                                        .set("lock_status", 2).eq("id", detailEntity.getId()));
                    }
                } else {
                    log.error("远程调用[orderFeignService.getOrderStatusByOrderSN]服务失败");
                    throw new RRException("远程调用服务失败");
                }
            }
        }
    }

    /**
     * 解锁库存
     *
     * @param to t0
     * @throws Exception 异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unlockStock(OrderTO to) {
        List<WareOrderTaskDetailEntity> list = wareOrderTaskDetailService
                .listDetailByOrderSnAndStatus(to.getOrderSn(), 1);
        if (CollUtil.isNotEmpty(list)) {
            for (WareOrderTaskDetailEntity entity : list) {
                entity.setLockStatus(2);
                baseMapper.unlockStock(entity.getSkuId(), entity.getSkuNum(), entity.getWareId());
            }
            wareOrderTaskDetailService.updateBatchById(list);
        }
    }
}
